package trail

import (
	"fmt"
	"sync"
	"time"
)

var concurrentGolab string = "how2j.online"

func chanlCon() {
	ch := make(chan string)

	defer func() {
		if r := recover(); r != nil {
			fmt.Printf("捕获到 1 个错误: %v\n", r)
		}
	}()

	go func() {
		ch <- "123 chan"
	}()

	msg := <-ch

	close(ch)
	ch <- "test"

	fmt.Printf(msg)
	fmt.Printf("\n")
}

func lockCon() {
	ch := make(chan string) // 没有设置通道的长度

	ch <- "hello world" // 向通道发送数据，但是没有接收者

	msg := <-ch // 代码执行不到这里, 因为上面阻塞发送数据时，就已经死锁了
	println(msg)
}

func watiGo() {
	var wg sync.WaitGroup // 声明一个wait实例
	wg.Add(1)             // 添加1个等待

	go func() {
		defer wg.Done()
		fmt.Println("wait group print")
	}()

	wg.Wait() // 等待所有goroutine执行完成
}

// 互斥锁
func mutexGo() {
	var mu sync.Mutex
	var wg sync.WaitGroup
	m := make(map[int]bool)

	for i := 0; i < 10; i++ {
		wg.Add(1)
		go func(key int) {
			defer wg.Done()
			mu.Lock()
			m[key] = true
			mu.Unlock()
		}(i)
	}
	wg.Wait()
	fmt.Printf("Map size = %d\n", len(m))
}

func timeOutGo() {
	ch := make(chan bool)
	go func() {
		defer func() {
			ch <- true
		}()
		time.Sleep(2 * time.Second)
	}()

	select {
	case ch1 := <-ch:
		fmt.Println("ok", ch1)
	case ch2 := <-time.After(3 * time.Second):
		fmt.Println("timeout", ch2)
	}
}

func manyNumAdd() {
	var num int32
	var wg sync.WaitGroup

	for i := 0; i < 1000; i++ {
		wg.Add(1)
		go func() {
			defer wg.Done()
			num++
		}()
	}
	wg.Wait()
	fmt.Printf("number = %d\n", num)
}

func ConcurrentMain() {
	manyNumAdd()
}
